const { exec } = require("child_process");
const { promisify } = require("util");
const fs = require("fs");
const path = require("path");
const archiver = require("archiver");
const AdmZip = require("adm-zip");
const execAsync = promisify(exec);
const mkdirAsync = promisify(fs.mkdir);
const accessAsync = promisify(fs.access);
const { format: dateFormat } = require("date-fns");
const readFileAsync = promisify(fs.readFile);
const writeFileAsync = promisify(fs.writeFile);
const renameAsync = promisify(fs.rename);
// 配置信息（修改以下路径为你的实际绝对路径）
let config = {};
// 文件修改操作
async function backupAndModifyFile(filePath) {
  try {
    // 备份原始内容
    config.modifyConfig.originalContent = await readFileAsync(filePath, "utf8");

    // 创建备份文件
    const backupPath = `${filePath}.bak`;
    await renameAsync(filePath, backupPath);

    // 写入新内容
    await writeFileAsync(filePath, config.modifyConfig.modifyContent);
    console.log("✅ 文件修改完成");
  } catch (error) {
    throw new Error(`文件操作失败: ${error.message}`);
  }
}

// 文件还原操作
async function restoreOriginalFile() {
  try {
    const targetFilePath = path.join(
      config.tempDir,
      config.modifyConfig.targetFile
    );
    const backupPath = `${targetFilePath}.bak`;

    // 删除修改后的文件
    await fs.promises.unlink(targetFilePath);

    // 还原备份文件
    await renameAsync(backupPath, targetFilePath);
    console.log("✅ 文件已还原");
  } catch (error) {
    console.error("⚠️ 文件还原失败:", error.message);
  }
}

async function main(val) {
  config = val;
  let restoreNeeded = false;
  // config.tempDir = path.join(__dirname, config.tempDir);
  try {
    // 标准化路径处理
    const normalizePath = (p) => path.normalize(p).replace(/\\/g, "/");

    // 转换配置路径
    config.tempDir = normalizePath(config.tempDir);
    console.log(config.tempDir,'config.tempDir')
    config.targetDir = normalizePath(config.targetDir);

    await ensureDirExists(config.tempDir);

    // 处理共享文件夹权限（可选）
    try {
      await accessAsync(config.targetDir, fs.constants.W_OK);
    } catch {
      throw new Error(`没有写入权限或路径不存在：${config.targetDir}`);
    }
    // 备份现有项目（如果存在）
    if (await directoryExists(config.targetDir)) {
      await backupProject();
    }
    // 克隆/更新仓库
    await handleGitRepository();
    // await modifyFile(path.join(config.tempDir, config.modifyFile));
    //修改目标文件
    const targetFilePath = path.join(
      config.tempDir,
      config.modifyConfig.targetFile
    );
    await backupAndModifyFile(targetFilePath);
    restoreNeeded = true;
    // 安装依赖
    // console.log('正在安装依赖...');
    // await execAsync('npm install', { cwd: config.tempDir });

    // 执行构建命令
    console.log("正在构建项目...");
    await execAsync(config.buildCommand, { cwd: config.tempDir });

    // 压缩文件
    const sourcePath = path.join(config.tempDir, config.sourceDir);
    const zipPath = path.join(__dirname, config.zipFileName);
    await zipDirectory(sourcePath, zipPath);

    // 准备目标目录
    await ensureDirExists(config.targetDir);

    // 解压到共享文件夹
    console.log("正在解压到共享文件夹...");
    const zip = new AdmZip(zipPath);
    zip.extractAllTo(config.targetDir, true);

    console.log("✅ 解压完成");
    console.log(`共享文件夹路径：${config.targetDir}`);
  } catch (error) {
    console.error("❌ 发生错误:", error);
    process.exit(1);
  } finally {
    if (restoreNeeded) {
      await restoreOriginalFile();
    }
  }
}

async function handleGitRepository() {
  try {
    await accessAsync(config.tempDir);
    console.log("正在更新已有仓库...");
    await execAsync("git pull", { cwd: config.tempDir });
  } catch {
    console.log("正在克隆新仓库...");
    await execAsync(`git clone ${config.repoUrl} ${config.tempDir}`);
  }
}
// 新增备份功能
async function backupProject() {
  try {
    console.log("正在创建备份...");

    // 创建备份目录
    await ensureDirExists(config.backupDir);

    // 生成带时间戳的备份文件名
    const timestamp = dateFormat(new Date(), "yyyyMMdd-HHmmss");
    const backupFileName = `backup_${timestamp}.zip`;
    const backupPath = path.join(config.backupDir, backupFileName);

    // 创建备份压缩包
    await zipDirectory(config.targetDir, backupPath);

    console.log(`✅ 备份成功：${backupPath}`);
  } catch (error) {
    throw new Error(`备份失败: ${error.message}`);
  }
}

// 新增目录存在检查
async function directoryExists(dirPath) {
  try {
    await accessAsync(dirPath);
    return true;
  } catch {
    return false;
  }
}

async function zipDirectory(source, outPath) {
  return new Promise((resolve, reject) => {
    console.log("正在压缩文件...");
    const output = fs.createWriteStream(outPath);
    const archive = archiver("zip", { zlib: { level: 9 } });

    output.on("close", () => {
      console.log(`压缩完成，文件大小：${archive.pointer()} bytes`);
      resolve();
    });

    archive.on("error", (err) => reject(err));
    archive.pipe(output);
    archive.directory(source, false);
    archive.finalize();
  });
}

async function ensureDirExists(dirPath) {
  try {
    await accessAsync(dirPath);
  } catch {
    await mkdirAsync(dirPath, { recursive: true });
    console.log(`已创建目录：${dirPath}`);
  }
}

// 路径标准化辅助函数
function formatSharedPath(inputPath) {
  // 处理Windows网络路径
  if (inputPath.startsWith("\\\\")) {
    return inputPath.replace(/\\/g, "/");
  }
  return path.resolve(inputPath);
}
// 新增权限检查函数
async function checkWritePermission(dirPath) {
  try {
    await accessAsync(dirPath, fs.constants.W_OK);
  } catch (error) {
    throw new Error(`无写入权限: ${dirPath} (${error.message})`);
  }
}
function modifyFile() {
  console.log(chalk.blue("\n🔧 修改配置文件..."));
  Object.entries(config.modifyFiles).forEach(([filePath, content]) => {
    const fullPath = path.join(config.paths.temp, filePath);
    const originalContent = fs.readFileSync(fullPath, "utf8");

    if (!originalContent.includes(content.original)) {
      throw new Error(`配置文件 ${filePath} 格式不符`);
    }

    // 备份原始文件
    fs.writeFileSync(`${fullPath}.bak`, originalContent);

    // 修改内容
    fs.writeFileSync(
      fullPath,
      originalContent.replace(content.original, content.modified)
    );
  });
}
module.exports = main;
